package com.xhs.hawaii.upload.service;

import com.alibaba.druid.util.StringUtils;
import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import com.xhs.hawaii.common.BusinessException;
import com.xhs.hawaii.upload.model.UploadFile;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

@Slf4j
@Service
public class QiniuService {

    @Value("${qiniu.access_key}")
    private String accessKey;
    @Value("${qiniu.secret_key}")
    private String secretKey;
    @Value("${qiniu.bucket_name}")
    private String bucketName;
    @Value("${qiniu.bucket_domain}")
    private String bucketDomian;
    @Value("${qiniu.bucket_expire}")
    private String expireInSeconds;

    @Value("${qiniu.public.bucket}")
    private String publicBucket;
    @Value("${qiniu.public_domain}")
    private String publicDomain;

    public String getUploadToken() {
        return getUploadToken(bucketName);
    }

    public String getUploadToken(String bucket) {
        Auth auth = Auth.create(accessKey, secretKey);
        String upToken = auth.uploadToken(bucket);
        return upToken;
    }


    public UploadFile upload(MultipartFile file) {
        try {
            return upload(new ByteArrayInputStream(file.getBytes()), file.getOriginalFilename());
        } catch (IOException e) {
            log.error("upload file", e);
            throw new BusinessException("上传文件失败", e);
        }

    }

    public UploadFile upload(InputStream in, String fileName) {
        //构造一个带指定Zone对象的配置类
        Configuration cfg = new Configuration(Zone.zone0());
        UploadManager uploadManager = new UploadManager(cfg);
        UploadFile uploadFile = new UploadFile();
        uploadFile.setOriginFileName(fileName);
        String upToken = getUploadToken();
        String key = null;
        if (!StringUtils.isEmpty(fileName)) {
            int x = fileName.lastIndexOf(".");
            if (x != -1) {
                key = fileName.substring(0, x) + System.currentTimeMillis() + fileName.substring(x);
            } else {
                key = fileName + System.currentTimeMillis();
            }
        }
        uploadFile.setUploadFileName(key);
        try {
            Response response = uploadManager.put(new BufferedInputStream(in), key, upToken, null, null);
            //解析上传成功的结果
            DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
            uploadFile.setUrl(bucketDomian + "/" + putRet.key);
            uploadFile.setDownloadUrl(getDownloadUrl(uploadFile.getUrl(), 3600));
            return uploadFile;
        } catch (QiniuException ex) {
            Response r = ex.response;
            log.error(r.getInfo(), ex);
            throw new BusinessException("上传文件失败", ex);
        }
    }

    public String getDownloadUrl(String url, long expireInSeconds) {
        if (url.contains("?")) {
            url = url.substring(0, url.indexOf("?"));
        }
        Auth auth = Auth.create(accessKey, secretKey);
        return auth.privateDownloadUrl(url, expireInSeconds);
    }


    /**
     * 上传至公有空间
     *
     * @param in
     * @param fileName
     * @return
     */
    public UploadFile uploadToPublicBucket(InputStream in, String fileName) {
        //构造一个带指定Zone对象的配置类
        Configuration cfg = new Configuration(Zone.zone0());
        UploadManager uploadManager = new UploadManager(cfg);
        UploadFile uploadFile = new UploadFile();
        uploadFile.setOriginFileName(fileName);
        String upToken = getUploadToken(publicBucket);
        String key = null;
        if (!StringUtils.isEmpty(fileName)) {
            int x = fileName.lastIndexOf(".");
            if (x != -1) {
                key = fileName.substring(0, x) + System.currentTimeMillis() + fileName.substring(x);
            } else {
                key = fileName + System.currentTimeMillis();
            }
        }
        uploadFile.setUploadFileName(key);
        try {
            Response response = uploadManager.put(new BufferedInputStream(in), key, upToken, null, null);
            //解析上传成功的结果
            DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
            uploadFile.setUrl(publicDomain + "/" + putRet.key);
            uploadFile.setDownloadUrl(publicDomain + "/" + putRet.key);
            return uploadFile;
        } catch (QiniuException ex) {
            Response r = ex.response;
            log.error(r.getInfo(), ex);
            throw new BusinessException("上传文件失败", ex);
        }
    }

    public UploadFile uploadToPublic(MultipartFile file) {
        try {
            return uploadToPublicBucket(new ByteArrayInputStream(file.getBytes()), file.getOriginalFilename());
        } catch (IOException e) {
            log.error("upload file", e);
            throw new BusinessException("上传文件失败", e);
        }

    }

    public void deletePublicFile(String fileKey) {
        //构造一个带指定Zone对象的配置类
        Configuration cfg = new Configuration(Zone.zone0());
        //...其他参数参考类注释
        Auth auth = Auth.create(accessKey, secretKey);
        BucketManager bucketManager = new BucketManager(auth, cfg);
        try {
            bucketManager.delete(publicBucket, fileKey);
        } catch (QiniuException ex) {
            log.error("delete file failed !", ex);
            throw new BusinessException("删除文件失败", ex.getMessage(), ex);
        }
    }
}
